package sdmaker.parser;

import sdmaker.ast.AST;
import sdmaker.ast.ASTalt;
import sdmaker.ast.ASTcall;
import sdmaker.ast.ASTloop;
import fsa.FSA;

public class SDMakerParser {
	
	public AST parse(FSA fsa){

		SDMakerGenerator generator= new SDMakerGenerator(fsa);
		StateData nextToParse= StateData.getStateData(fsa.getInitialState());
		SetStateData seenStates= new SetStateData();
		SetStateData forbiddenStates= new SetStateData(); //no forbidden states initially
		
		do{
			parseState(generator, nextToParse, seenStates, forbiddenStates);

			if(nextToParse.fullParsed(forbiddenStates)){
				nextToParse= seenStates.firstNotFullParsedFIFO(forbiddenStates);
			}
			
		}while(nextToParse!=null);

		return generator.generateFinalAST();
	}

	public static void parseState(
			SDMakerGenerator generator, StateData n, 
			SetStateData seenStates, SetStateData forbiddenStates){

		if(ASTalt.isAlternative(n, seenStates, forbiddenStates)){
			ASTalt.parseAlt(generator, n, seenStates, forbiddenStates);
		}
		if(ASTloop.leadToLoop(n, seenStates, forbiddenStates)){ 
			ASTloop.parseLoop(generator, n, seenStates, forbiddenStates);
		}
		else if(ASTcall.leadToSimpleCall(n, seenStates, forbiddenStates)){
			ASTcall.parseSimpleCall(generator, n, seenStates, forbiddenStates);
		}
		else if(ASTcall.leadToNestedCall(n, seenStates, forbiddenStates)){
			ASTcall.parseNestedCall(generator, n, seenStates, forbiddenStates);
		}
		else{ //must be the end
			seenStates.add(n);
		}
	}
}
